package com.akk.module.hkpay.service;

import com.akk.PayConstants;
import com.akk.module.hkpay.model.*;
import com.akk.module.hkpay.util.HkUtils;
import com.akk.module.hlbpay.util.HlbBeanUtils;
import com.akk.module.hxt.utils.HttpClientHelper;
import com.akk.module.hxt.utils.HttpResponse;
import com.akk.utils.IDUtils;
import com.akk.utils.Md5Utils;
import com.akk.utils.RestResponse;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.springframework.stereotype.Component;

import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;


/*汇卡支付*/
@Component
public class HkPayService {


    // 创建订单
    public RestResponse createOrder(HkCreateOrderRequest request) {
        request.setVersion(PayConstants.HK_VERSION);
        request.setHicardMerchNo(PayConstants.HK_MERCH_NUMBER);
        request.setOrganNo(PayConstants.HK_ORGAN_NUMBER);
//        request.setBackEndUrl("www.baidu.com");
//        request.setFrontEndUrl("www.baidu.com");
        request.setBizType("812");
        request.setIsT0("1");
        request.setShowPage("");
        request.setAmount(((int) Double.parseDouble(request.getAmount()) * 100) + "");
        StringBuilder sb = new StringBuilder();
        sb.append("version=" + request.getVersion() + "&");
        sb.append("organNo=" + request.getOrganNo() + "&");
        sb.append("hicardMerchNo=" + request.getHicardMerchNo() + "&");
        sb.append("payType=" + request.getPayType() + "&");
        sb.append("bizType=" + request.getBizType() + "&");
        sb.append("merchOrderNo=" + request.getMerchOrderNo() + "&");
        sb.append("showPage=" + request.getShowPage() + "&");
        sb.append("amount=" + request.getAmount() + "&");
        sb.append("frontEndUrl=" + request.getFrontEndUrl() + "&");
        sb.append("backEndUrl=" + request.getBackEndUrl() + "&");
        sb.append(PayConstants.HK_MD5_SIGN_KEY);
        request.setSign(Md5Utils.md5_low(sb.toString()));
        System.out.println("req:" + JSON.toJSONString(request));
        HttpResponse resultMap = HttpClientHelper.doHttp(PayConstants.HK_CREATE_ORDER_URL, HttpClientHelper.POST, "utf-8", JSON.toJSONString(request), "60000");
        System.out.println("res:" + resultMap.getRspStr());
        if (resultMap.getStatusCode() == HttpStatus.SC_OK) {
            Gson gson = new Gson();
            HkCreateOrderResponse response = gson.fromJson(resultMap.getRspStr(), HkCreateOrderResponse.class);
            if (response.getRespCode().equals("00")) {
                return RestResponse.build(response);
            } else {
                return RestResponse.build(RestResponse.AVS_ERROR_CODE, response.getRespMsg(), response);
            }
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "请求失败");
    }

    // T0查询
    public RestResponse t0Query(String merchOrderNo) {
        HkT0QueryRequest request = new HkT0QueryRequest();
        request.setMerchOrderNo(merchOrderNo);
        request.setHicardMerchNo(PayConstants.HK_MERCH_NUMBER);
        request.setVersion(PayConstants.HK_VERSION);
        request.setOrganNo(PayConstants.HK_ORGAN_NUMBER);
        StringBuilder sb = new StringBuilder();
        sb.append("version=" + request.getVersion() + "&");
        sb.append("organNo=" + request.getOrganNo() + "&");
        sb.append("merchOrderNo=" + request.getHicardMerchNo() + "&");
        sb.append("hicardOrderNo=" + request.getMerchOrderNo() + "&");
        sb.append(PayConstants.HK_MD5_SIGN_KEY);
        request.setSign(Md5Utils.md5_low(sb.toString()));
        System.out.println(JSON.toJSONString(request));
        HttpResponse resultMap = HttpClientHelper.doHttp(PayConstants.HK_T0_QUERY_URL, HttpClientHelper.POST, "utf-8", JSON.toJSONString(request), "60000", "text/plain;charset=UTF-8", null);
        if (resultMap!=null && resultMap.getStatusCode() == HttpStatus.SC_OK) {
            HkT0QueryResponse response = new Gson().fromJson(resultMap.getRspStr(), HkT0QueryResponse.class);
            if (response.getRespCode().equals("00")) {
                return RestResponse.build(response);
            } else {
                return RestResponse.build(RestResponse.AVS_ERROR_CODE, response.getRespMsg());
            }
        }
        return null;
    }

    @Test
    public void test3() {
        RestResponse response = t0Query("MM96531872350532");
        System.out.println(new Gson().toJson(response));
    }

    @Test
    public void test() {
        HkCreateOrderRequest request = new HkCreateOrderRequest();
        request.setPayType("016");
        request.setBizType("812");
        request.setAmount("99.0");
        request.setGoodsName("haha");
        request.setCertsNo("511621199403025111");
        request.setOpenId("123456789");
        request.setSubAppId("00001");
        request.setRemark("haha");
        request.setTransIP("192.168.1.179");
        request.setReserved("haha");
        request.setIsT0("1");
        request.setMerchOrderNo("12312321312321312");
        createOrder(request);
    }

    // 订单查询
    public RestResponse hkOrderQuery(HkOrderQueryRequest request) {
        request.setVersion(PayConstants.HK_VERSION);
        request.setHicardMerchNo(PayConstants.HK_MERCH_NUMBER);
        request.setOrganNo(PayConstants.HK_ORGAN_NUMBER);
        StringBuilder sb = new StringBuilder();
        sb.append("version=" + request.getVersion() + "&");
        sb.append("hicardMerchNo=" + request.getHicardMerchNo() + "&");
        sb.append("merchOrderNo=" + request.getMerchOrderNo() + "&");
        sb.append("hicardOrderNo=" + request.getHicardOrderNo() + "&");
        sb.append(PayConstants.HK_MD5_SIGN_KEY);
        request.setSign(Md5Utils.md5_low(sb.toString()));
        HttpResponse resultMap = HttpClientHelper.doHttp(PayConstants.HK_ORDER_QUERY_URL, HttpClientHelper.POST, "utf-8", JSON.toJSONString(request), "60000");
        if (resultMap.getStatusCode() == HttpStatus.SC_OK) {
            HkOrderQueryResponse response = new Gson().fromJson(resultMap.getRspStr(), HkOrderQueryResponse.class);
            if (response.getRespCode().equals("00")) {
                return RestResponse.build(response);
            } else {
                return RestResponse.build(RestResponse.AVS_ERROR_CODE, response.getRespMsg());
            }
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "服务器繁忙");
    }

    @Test
    public void test2() {
        HkOrderQueryRequest request = new HkOrderQueryRequest();
        request.setMerchOrderNo("MM96531872350532");
        request.setHicardOrderNo("4161711080093623");
        request.setCreateTime("20171108153355");
        RestResponse restResponse = hkOrderQuery(request);
        System.out.println(new Gson().toJson(restResponse));
    }

    // 扫码支付
    public RestResponse hkQrCodeScanPay(HkQrCodeScanPayRequest request) {
        request.setVersion(PayConstants.HK_VERSION);
        request.setHicardMerchNo(PayConstants.HK_MERCH_NUMBER);
        request.setOrganNo(PayConstants.HK_ORGAN_NUMBER);
        request.setIsT0("0");
        request.setBackEndUrl(PayConstants.HK_QR_CODE_SCAN_PAY_CALL_BACK);
        request.setPayType("016");
        request.setBizType("812");
        StringBuilder sb = new StringBuilder();
        sb.append("version=" + request.getVersion() + "&");
        sb.append("organNo=" + request.getOrganNo() + "&");
        sb.append("hicardMerchNo=" + request.getHicardMerchNo() + "&");
        sb.append("merchOrderNo=" + request.getMerchOrderNo() + "&");
        sb.append("goodsName=" + request.getGoodsName() + "&");
        sb.append("amount=" + request.getAmount() + "&");
        sb.append("authCode=" + request.getAuthCode() + "&");
        sb.append("payType=" + request.getPayType() + "&");
        sb.append(PayConstants.HK_MD5_SIGN_KEY);
        request.setSign(Md5Utils.md5_low(sb.toString()));
        System.out.println(JSON.toJSONString(request));
        HttpResponse resultMap = HttpClientHelper.doHttp(PayConstants.HK_QR_CODE_SCAN_URL, HttpClientHelper.POST, "utf-8", JSON.toJSONString(request), "60000");
        if (resultMap.getStatusCode() == HttpStatus.SC_OK) {
            HkQrCodeScanPayResponse response = new Gson().fromJson(resultMap.getRspStr(), HkQrCodeScanPayResponse.class);
            if (response.getRespCode().equals("00")) {
                return RestResponse.build(response);
            } else {
                return RestResponse.build(RestResponse.AVS_ERROR_CODE, response.getRespMsg());
            }
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "服务器繁忙");
    }

    public RestResponse HkRefund(HkRefundRequest request) {
        request.setVersion(PayConstants.HK_VERSION);
        request.setHicardMerchNo(PayConstants.HK_MERCH_NUMBER);
        request.setOrganNo(PayConstants.HK_ORGAN_NUMBER);
        StringBuilder sb = new StringBuilder();
        sb.append("version=" + request.getVersion() + "&");
        sb.append("organNo=" + request.getOrganNo() + "&");
        sb.append("hicardMerchNo=" + request.getHicardMerchNo() + "&");
        sb.append("merchOrderNo=" + request.getMerchOrderNo() + "&");
        sb.append("refundMerchOrderNo=" + request.getRefundMerchOrderNo() + "&");
        sb.append("backEndUrl=" + request.getBackEndUrl() + "&");
        sb.append("refundMoney=" + request.getBackEndUrl() + "&");
        sb.append(PayConstants.HK_MD5_SIGN_KEY);
        request.setSign(Md5Utils.md5_low(sb.toString()));
        System.out.println(JSON.toJSONString(request));
        HttpResponse resultMap = HttpClientHelper.doHttp(PayConstants.HK_REFUND_URL, HttpClientHelper.POST, "utf-8", JSON.toJSONString(request), "60000");
        if (resultMap.getStatusCode() == HttpStatus.SC_OK) {
            HkRefundResponse response = new Gson().fromJson(resultMap.getRspStr(), HkRefundResponse.class);
            if (response.getRespCode().equals("00")) {
                return RestResponse.build(response);
            } else {
                return RestResponse.build(RestResponse.AVS_ERROR_CODE, response.getRespMsg());
            }
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "服务器繁忙");
    }

    // 银行卡验证
    public RestResponse hkBankCardVerify(HkBankCardVerifyRequest request) {
        request.setVersion(PayConstants.HK_VERSION);
        request.setHicardMerchNo(PayConstants.HK_MERCH_NUMBER);
        request.setOrganNo(PayConstants.HK_ORGAN_NUMBER);
        StringBuilder sb = new StringBuilder();
        sb.append("version=" + request.getVersion() + "&");
        sb.append("organNo=" + request.getHicardMerchNo() + "&");
        sb.append("hicardOrderNo=" + request.getHicardMerchNo() + "&");
        sb.append("merchOrderNo=" + request.getMerchOrderNo() + "&");
        sb.append("name=" + request.getName() + "&");
        sb.append("cardNo=" + request.getCardNo() + "&");
        sb.append("pid=" + request.getPid() + "&");
        sb.append("cellPhoneNo=" + request.getCellPhoneNo() + "&");
        sb.append(PayConstants.HK_MD5_SIGN_KEY);
        request.setSign(Md5Utils.md5_low(sb.toString()));
        HttpResponse resultMap = HttpClientHelper.doHttp(PayConstants.HK_BANK_CARD_VERIFY_URL, HttpClientHelper.POST, "utf-8", JSON.toJSONString(request), "60000");
        if (resultMap.getStatusCode() == HttpStatus.SC_OK) {
            HkBankCardVerifyResponse response = new Gson().fromJson(resultMap.getRspStr(), HkBankCardVerifyResponse.class);
            if (response.getRespCode().equals("00")) {
                return RestResponse.build(response);
            }
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, response.getRespMsg(), response);
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "请求失败");
    }

    @Test
    public void test4() {
        HkBankCardVerifyRequest request = new HkBankCardVerifyRequest();
        request.setMerchOrderNo(IDUtils.getUniqueNum14());
        request.setName("李正");
        request.setCardNo("6231561600104912");
        request.setPid("511921199508216738");
        request.setCellPhoneNo("17761265912");

    }

    // 代付
    public RestResponse withdrawal(HkWithdrawalRequest request) {
        // 请求头
        LinkedHashMap<String, String> reqHeader = new LinkedHashMap<String, String>();
        reqHeader.put("version", "100"); // 版本号
        reqHeader.put("security", "none"); // 安全模式
        reqHeader.put("transType", "7011"); // 接口类型
        reqHeader.put("dtClient", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 客户端时间戳
        reqHeader.put("channelType", "5"); // 渠道类型
        String responseJson = "";
        try {
            // 请求内容
            LinkedHashMap<String, String> reqBody = (LinkedHashMap<String, String>) HlbBeanUtils.convertBean(request, new LinkedHashMap());
            reqBody.put("signature", HkUtils.sign(reqBody, PayConstants.HK_CARD_WALLET_KEY, "key")); // 签名
            // 完整请求
            LinkedHashMap<String, Object> req = new LinkedHashMap<>();
            req.put("header", reqHeader);
            req.put("body", reqBody);
            // 转json
            String requestJson = new Gson().toJson(req);
            System.out.println(requestJson);
            // 客户端
            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost hp = new HttpPost(PayConstants.HK_CARD_WALLET_URL);
            hp.setEntity(new StringEntity(requestJson, Charset.forName("UTF-8")));
            org.apache.http.HttpResponse response = client.execute(hp);
            int statusCode = response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            byte[] respContent = EntityUtils.toByteArray(entity);
            EntityUtils.consume(entity);
            if (statusCode != 200) {
                return RestResponse.build(RestResponse.AVS_ERROR_CODE, "请求失败");
            }
            responseJson = new String(respContent, Charset.forName("UTF-8"));
            client.close();

            System.out.println(responseJson);
            if (!StringUtils.isEmpty(responseJson)) {
                JsonObject object = new JsonParser().parse(responseJson).getAsJsonObject();
                JsonObject body = object.getAsJsonObject("body");
                if (body.has("code") && !body.get("code").getAsString().equals("0000")) {
                    return RestResponse.build(RestResponse.AVS_ERROR_CODE, body.get("message").getAsString());
                } else if (body.has("respCode") && !body.get("respCode").getAsString().equals("0000")) {
                    return RestResponse.build(RestResponse.AVS_ERROR_CODE, body.get("respMessage").getAsString());
                } else {
                    return RestResponse.build(body);
                }
            }
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, responseJson);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "请求失败");
    }


    // 根据外部商户号查询汇卡商户号
    public RestResponse queryMerNo(String payerId){
        Map<String,String> header = new HashMap<>();
        header.put("Version","100");
        header.put("TransType","S1053");
        header.put("DataTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        header.put("SerialNo",IDUtils.getUniqueNum14());
        Map<String,String> appBody = new HashMap<>();
        appBody.put("institutionNo",PayConstants.HK_ORGAN_NUMBER);
        appBody.put("extMerNo",payerId);
        appBody.put("password",PayConstants.HK_REG_MER_KEY);
        Map<String,Object> param = new HashMap<>();
        param.put("AppHead",header);
        param.put("AppBody",appBody);
        HttpResponse response = HttpClientHelper.doHttp(PayConstants.HK_MER_REG_URL, HttpClientHelper.POST, "utf-8", new Gson().toJson(param), "60000");
        if (response.getStatusCode() == HttpStatus.SC_OK) {
            return RestResponse.build(response.getRspStr());
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "商户入网失败");
    }

    @Test
    public void test9(){
        RestResponse restResponse = queryMerNo("7de0a5aa9259489ab916262e97a9d41d");
        System.out.println(new Gson().toJson(restResponse));
    }

    // 提现
    @Test
    public void test5() {
        HkWithdrawalRequest request = new HkWithdrawalRequest();
        request.setAmount("1");
        request.setInNo("104401581003105");
        request.setOutNo("104401581003105");
        request.setInstNo("99999999");
        request.setOrderNo(IDUtils.getUniqueNum14());
        request.setOrderTime("2017-11-14 13:20:22");
        request.setTradeSequence(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        request.setRemark("备注");
        request.setUseT0Amount("N");
        request.setType("M2C");
        RestResponse response = withdrawal(request);
        System.out.println(response.getMessage());
    }

    public RestResponse merReg(HkMerRegRequest request) {
        try {
            Map appHeader = new HashMap();
            appHeader.put("Version", "100");
            appHeader.put("TransType", "S1050");
            appHeader.put("DataTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            appHeader.put("SerialNo", IDUtils.getUniqueNum14());
            Map appBody = HlbBeanUtils.convertBean(request, new LinkedHashMap());
            Map<String, Object> appMap = new HashMap<String, Object>();
            appMap.put("AppHead", appHeader);
            appMap.put("AppBody", appBody);
            String json = new Gson().toJson(appMap);
            String[] nos = {"sign","mbiType","extMerNo","liquidateModle","defaultWalletAccount"};
            String url = HkUtils.createSortUrl(json,nos);
            url += "1a861edc704121753369894d7afc9596";
            String signByCustomer = DigestUtils.md5Hex(url).toUpperCase();
            appBody.put("sign", signByCustomer);
            json = new Gson().toJson(appMap);
            HttpResponse response = HttpClientHelper.doHttp(PayConstants.HK_MER_REG_URL, HttpClientHelper.POST, "utf-8", json, "60000");
            if (response.getStatusCode() == HttpStatus.SC_OK) {
                return RestResponse.build(response.getRspStr());
            }
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "商户入网失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return RestResponse.build(RestResponse.AVS_ERROR_CODE, "服务器繁忙");
    }

    @Test
    public void testReg() {
        HkMerRegRequest request = new HkMerRegRequest();
        request.setInstitutionNo("99999999");
        request.setMerName("李正");
        request.setMerNameShort("李正");
        request.setMerAddress("成都市锦江区");
        request.setMerLegalName("李正");
        request.setMerLegalNo("511921199508216738");
        request.setMerLegalMobilePhone("17761265912");
        request.setPosAreaCode("2222");
        request.setMbiAccountNo("6231561600104912");
        request.setMbiBankName("光大银行");
        request.setMbiAccountUser("李正");
        request.setMbiBankNo("303651000907");
        request.setBusiNo("0311");
        request.setRateId("1743");
        request.setExtMerNo("");
        RestResponse restResponse = merReg(request);
    }

//    private static String createSortUrl(String json) {
//        StringBuilder sb = new StringBuilder();
//        try {
//            ObjectMapper objectMapper = new ObjectMapper();
//            Map<String, Object> maps = objectMapper.readValue(json, Map.class);
//            Map<String, Object> appBody = (Map<String, Object>) maps.get("AppBody");
//            Set<String> set = appBody.keySet();
//
//            // 删除不参与签名校验的字段
//            appBody.remove("mbiType");
//            appBody.remove("extMerNo");
//
//            // 排序
//            Set<String> sortSet = new TreeSet<String>();
//            sortSet.addAll(set);
//
//            // 删除sign
//            sortSet.remove("sign");
//
//            // 构造url
//            Iterator<String> it = sortSet.iterator();
//            while (it.hasNext()) {
//                String key = it.next();
//                Object value = appBody.get(key);
//                sb.append("&").append(key).append("=").append(value);
//            }
//            sb.append("&key=");
//        } catch (Exception e) {
//            e.printStackTrace();
//            sb.append("&");
//        }
//        return sb.substring(1);
//    }

}